#include "TextureScript.hpp"
#include <Utility/Tools.hpp>
#include <Utility/FileTools.hpp>
#include <Utility/StringTools.hpp>


namespace zzz{
int TextureInt(const string &str)
{
  string str1;
  if (str[0]=='g' && str[1]=='l' && str[2]=='_') str1.assign(str.begin()+3,str.end());
  else str1=str;
  //internal
  if (str1=="alpha") return GL_ALPHA;
  if (str1=="alpha4") return GL_ALPHA4;
  if (str1=="alpha8") return GL_ALPHA8;
  if (str1=="alpha12") return GL_ALPHA12;
  if (str1=="alpha16") return GL_ALPHA16;
  if (str1=="luminance") return GL_LUMINANCE;
  if (str1=="luminance4") return GL_LUMINANCE4;
  if (str1=="luminance8") return GL_LUMINANCE8;
  if (str1=="luminance12") return GL_LUMINANCE12;
  if (str1=="luminance12") return GL_LUMINANCE16;
  if (str1=="luminance_alpha") return GL_LUMINANCE_ALPHA;
  if (str1=="luminance4_alpha4") return GL_LUMINANCE4_ALPHA4;
  if (str1=="luminance6_alpha2") return GL_LUMINANCE6_ALPHA2;
  if (str1=="luminance8_alpha8") return GL_LUMINANCE8_ALPHA8;
  if (str1=="luminance12_alpha4") return GL_LUMINANCE12_ALPHA4;
  if (str1=="luminance12_alpha12") return GL_LUMINANCE12_ALPHA12;
  if (str1=="luminance16_alpha16") return GL_LUMINANCE16_ALPHA16;
  if (str1=="intensity") return GL_INTENSITY;
  if (str1=="intensity4") return GL_INTENSITY4;
  if (str1=="intensity8") return GL_INTENSITY8;
  if (str1=="intensity12") return GL_INTENSITY12;
  if (str1=="intensity16") return GL_INTENSITY16;
  if (str1=="r3_g3_b2") return GL_R3_G3_B2;
  if (str1=="rgb") return GL_RGB;
  if (str1=="rgb4") return GL_RGB4;
  if (str1=="rgb5") return GL_RGB5;
  if (str1=="rgb8") return GL_RGB8;
  if (str1=="rgb10") return GL_RGB10;
  if (str1=="rgb12") return GL_RGB12;
  if (str1=="rgb16") return GL_RGB16;
  if (str1=="rgba") return GL_RGBA;
  if (str1=="rgba2") return GL_RGBA2;
  if (str1=="rgba4") return GL_RGBA4;
  if (str1=="rgb5_a1") return GL_RGB5_A1;
  if (str1=="rgba8") return GL_RGBA8;
  if (str1=="rgb10_a2") return GL_RGB10_A2;
  if (str1=="rgba12") return GL_RGBA12;
  if (str1=="rgba16") return GL_RGBA16;

  if (str1=="rgba32f") return GL_RGBA32F_ARB;
  if (str1=="rgb32f") return GL_RGB32F_ARB;
  if (str1=="alpha32f") return GL_ALPHA32F_ARB;
  if (str1=="intensity32f") return GL_INTENSITY32F_ARB;
  if (str1=="luminance32f") return GL_LUMINANCE32F_ARB;
  if (str1=="luminance_alpha32f") return GL_LUMINANCE_ALPHA32F_ARB;
  if (str1=="rgba16f") return GL_RGBA16F_ARB;
  if (str1=="rgb16f") return GL_RGB16F_ARB;
  if (str1=="alpha16f") return GL_ALPHA16F_ARB;
  if (str1=="intensity16f") return GL_INTENSITY16F_ARB;
  if (str1=="luminance16f") return GL_LUMINANCE16F_ARB;
  if (str1=="luminance_alpha16f") return GL_LUMINANCE_ALPHA16F_ARB;

  if (str1=="depth_component") return GL_DEPTH_COMPONENT;
  if (str1=="depth_component16") return GL_DEPTH_COMPONENT16;
  if (str1=="depth_component24") return GL_DEPTH_COMPONENT24;
  if (str1=="depth_component32") return GL_DEPTH_COMPONENT32;
  //format
  if (str1=="color_index") return GL_COLOR_INDEX;
  if (str1=="red") return GL_RED;
  if (str1=="blue") return GL_BLUE;
  if (str1=="green") return GL_GREEN;
  if (str1=="bgr") return GL_BGR;
  if (str1=="bgra") return GL_BGRA;
  //type
  if (str1=="double") return GL_DOUBLE;
  if (str1=="float") return GL_FLOAT;
  if (str1=="unsigned_byte") return GL_UNSIGNED_BYTE;
  if (str1=="byte") return GL_BYTE;
  if (str1=="bitmap") return GL_BITMAP;
  if (str1=="unsigned_short") return GL_UNSIGNED_SHORT;
  if (str1=="short") return GL_SHORT;
  if (str1=="unsigned_int") return GL_UNSIGNED_INT;
  if (str1=="int") return GL_INT;
  return 0;
}
inline bool TextureConst(const string &str, int &ret)
{
  ret=TextureInt(str);
  if (ret==0) return false;
  else return true;
}


bool Script<Texture2D>::LoadFromMemory( istringstream &iss, Texture2D &t, const string &path )
{
  string tmp;
  int tmpi;
  while(true)
  {
    iss>>tmp;
    if (iss.fail()) break;
    ToLow(tmp);
    if (tmp=="f" || tmp=="file")
    {
      iss>>tmp;
      tmp=PathFile(path,tmp);
      t.Create(tmp.c_str());
    }
    else if (tmp=="s" || tmp=="size")
    {
      float width,height;
      iss>>width>>height;
      t.ChangeSize(width,height);
    }
    else if (tmp=="i" || tmp=="iformat" || tmp=="internalformat")
    {
      iss>>tmp;
      if (TextureConst(tmp,tmpi)) t.ChangeInternalFormat(tmpi);
      else printf("UNKNOWN CONSTANT: %s\n",tmp.c_str());
    }
    else
    {
      printf("UNKNOWN PARAMETER: %s\n",tmp.c_str());
      return false;
    }
  }
  return true;
}

bool Script<TextureCube>::LoadFromMemory( istringstream &iss, TextureCube &t, const string &path )
{
  string tmp;
  int tmpi;
  while(true)
  {
    iss>>tmp;
    if (iss.fail()) break;
    ToLow(tmp);
    if (tmp=="f" || tmp=="file")
    {
      iss>>tmp;
      tmp=PathFile(path,tmp);
      t.Create(tmp.c_str());
    }
    else if (tmp=="files")
    {
      string posx,posy,posz,negx,negy,negz;
      iss>>posx;
      posx=PathFile(path,posx);
      iss>>negx;
      negx=PathFile(path,negx);
      iss>>posy;
      posy=PathFile(path,posy);
      iss>>negy;
      negy=PathFile(path,negy);
      iss>>posz;
      posz=PathFile(path,posz);
      iss>>negz;
      negz=PathFile(path,negz);
      t.Create(posx.c_str(),negx.c_str(),posy.c_str(),negy.c_str(),posz.c_str(),negz.c_str());
    }
    else if (tmp=="s" || tmp=="size")
    {
      float width,height;
      iss>>width>>height;
      t.ChangeSize(width,height);
    }
    else if (tmp=="c" || tmp=="cubesize")
    {
      float size;
      iss>>size;
      t.ChangeSize(size);
    }
    else if (tmp=="i" || tmp=="internalformat")
    {
      iss>>tmp;
      if (TextureConst(tmp,tmpi)) t.ChangeInternalFormat(tmpi);
      else printf("UNKNOWN CONSTANT: %s\n",tmp.c_str());
    }
    else
    {
      printf("UNKNOWN PARAMETER: %s\n",tmp.c_str());
      return false;
    }
  }
  return true;
}
}